package com.example.verification.demo.common.util;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by hzy on 2018/9/14.
 */

public class JacksonUtils {
    private static final Logger logger = LoggerFactory.getLogger(JacksonUtils.class);
    private final static ObjectMapper objectMapper = new ObjectMapper();

    static {
//        //去掉默认的时间戳格式
//        objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
//        //设置为中国上海时区
//        objectMapper.setTimeZone(TimeZone.getTimeZone("GMT+8"));
//        //空值不序列化
//        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
//        //序列化时，日期的统一格式
//        objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));

        //
        objectMapper.configure(JsonParser.Feature.ALLOW_COMMENTS, true); // 支持Json中带有注释
        objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);// 这个特性决定parser是否将允许使用非双引号属性名字
        objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_CONTROL_CHARS, true);//该特性决定parser是否允许JSON字符串包含非引号控制字符（值小于32的ASCII字符，包含制表符和换行符）
        objectMapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true); // 支持单引号
    }

    /**
     * javaBean,list,array convert to json string
     */
    public static String bean2Json(Object obj) {
        try {
            return objectMapper.writeValueAsString(obj);
        } catch (Exception e) {
            logger.error("bean2Json(Object)", e);
        }
        return null;
    }


    /**
     * json string convert to javaBean
     */
    public static <T> T json2Bean(String jsonStr, Class<T> clazz) {
        try {
            return objectMapper.readValue(jsonStr, clazz);
        } catch (Exception e) {
            logger.error("json2Bean(String jsonStr, Class<T> clazz)", e);
            return null;
        }
    }

    /**
     * 将json array反序列化为对象
     */
    @SuppressWarnings("unchecked")
    public static <T> T jsonArr2Bean(String json, TypeReference<T> typeReference) {
        try {
            return (T) objectMapper.readValue(json, typeReference);
        } catch (Exception e) {
            logger.error("jsonArr2Bean(String, JsonTypeReference<T>)", e);
            return null;
        }
    }



    /**
     * json array string convert to list with javaBean
     */
    public static <T > List < T > json2List(String jsonArrayStr, Class < T > clazz){
        List<Map<String, Object>> list = null;
        try {
            list = objectMapper.readValue(jsonArrayStr, new TypeReference<List<T>>() {});
        } catch (IOException e) {
            logger.error("jsonArr2Bean(String jsonArrayStr, Class < T > clazz)", e);
        }

        if (list == null) {
            return null;
        }

        List<T> result = new ArrayList<>();
        for (Map<String, Object> map : list) {
            result.add(map2pojo(map, clazz));
        }
        return result;
    }


    /**
     * json string convert to map
     */
    public static <T> Map<String, Object> json2map(String jsonStr) {
        try {
            return objectMapper.readValue(jsonStr,new TypeReference<Map<String, Object>>() {});
        } catch (IOException e) {
            logger.error("json2map(String jsonStr)",e);
        }
        return null;
    }


    /**
     * json string convert to map with javaBean
     */
    public static <T> Map<String, T> json2Map(String jsonStr, Class<T> clazz) {
        Map<String, Map<String, Object>> map = null;
        try {
            map = objectMapper.readValue(jsonStr, new TypeReference<Map<String, T>>() {});
        } catch (IOException e) {
            logger.error("json2Map(String jsonStr, Class<T> clazz)", e);
        }
        Map<String, T> result = new HashMap<String, T>();
        for (Map.Entry<String, Map<String, Object>> entry : map.entrySet()) {
            result.put(entry.getKey(), map2pojo(entry.getValue(), clazz));
        }
        return result;
    }

    /**
     * map convert to javaBean
     */
    public static <T> T map2pojo(Map map, Class<T> clazz) {
        return objectMapper.convertValue(map, clazz);
    }


    /**
     *  美化输出
     */
    public static <T> String pretty(T t){
        ObjectMapper mapper = new ObjectMapper();
        mapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);//设置可用单引号
        mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);//设置字段可以不用双引号包括
        mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
        String json = "";
        try {
            json = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(t);
        } catch (Exception e) {
            logger.error("console(T t)",e);
        }
        return json;
    }
}
